import tempfile

class FitParameterTeXTable(object):
    col3header = r"\begin{tabular}{lll}"
#    group_header = r"\begin{{center}}{0}\end{{center}}"
    group_header = r"{0}\\"
    col3param  = "\t" + r"${0}$ &= {1:> .4g}&$\pm${2:.3g}{3}"

    close_table = r"\end{tabular}" + "\n"
    vskip = r"\vskip 1mm"
    hline = "\t" + r"\hline"

    chi2header = r"\begin{tabular}{ll}"
    chi2i = "\t" + r"Initial $\chi^2$/d.o.f.:& {0:.3f} \\"
    chi2f = "\t" + r"Final $\chi^2$/d.o.f.:& {0:.3f}"

    def __init__(self):        
        self.buffer = []

    def add_group(self, group, header=None):
        if header is not None:
            self.buffer.append(FitParameterTeXTable.group_header.format(header))
            self.buffer.append(FitParameterTeXTable.col3header)
            self.buffer.append(FitParameterTeXTable.hline)
        else:
            self.buffer.append(FitParameterTeXTable.col3header)

        return_chars = [r'\\']*len(group)
#        return_chars[-1] = ''
        for i, param in enumerate(group):
            self.buffer.append(FitParameterTeXTable.col3param.format(param[0],
                                                                     param[1],
                                                                     param[2],
                                                                     return_chars[i]))

#        self.buffer.append(FitParameterTeXTable.hline)
        self.buffer.append(FitParameterTeXTable.close_table)
        self.buffer.append(FitParameterTeXTable.vskip)

    def add_chi2(self, chi2i, chi2f):
        self.buffer.append(FitParameterTeXTable.chi2header)
        self.buffer.append(FitParameterTeXTable.chi2i.format(chi2i))
        self.buffer.append(FitParameterTeXTable.chi2f.format(chi2f))
        self.buffer.append(FitParameterTeXTable.close_table)


    def write(self):
        tf = tempfile.NamedTemporaryFile(suffix='.tex')

#        tf = open("/scratch/tmp.tex", 'w')

        if self.buffer[-1] == FitParameterTeXTable.vskip:
            tf.write('\n'.join(self.buffer[:-1]))    
        else:
            tf.write('\n'.join(self.buffer))
        
        tf.write('\n')
        tf.flush()
        tf.seek(0)

        return tf




def write_minuit_table(m, initial_chi2=None, final_chi2=None, param_names=None, param_latex=None):
#    tf = open("minuit_table.tex", 'w')

    print initial_chi2, final_chi2
    tf = tempfile.NamedTemporaryFile(suffix='.tex')
    
    tf.write(r'''
\begin{tabular}{lll}
''')
    
    if not param_names:
        raise NotImplementedError("Not sure what to do if you don't give me parameter names.")

    for name in param_names:
        tf.write(r'''
    ${0}$ &= {1:> .3g}&$\pm${2:.3g}\\
'''.format(param_latex[name], m.values[name], m.errors[name]))
    
    tf.write(r'''
\hline
\end{tabular}
''')

    if initial_chi2 is not None and final_chi2 is not None:
        tf.write(r'''

\vskip 5mm
    
\begin{tabular}{ll}
''')
        tf.write(r'''
    Initial $\chi^2$/d.o.f.& {0:.3g} \\
    Final $\chi^2$/d.o.f.& {1:.3g}
'''.format(initial_chi2, final_chi2))
        tf.write(r'''
\end{tabular}
''')
    tf.flush()
    tf.seek(0)

    return tf
        

table = r'''
\begin{{tabular}}{{lll}}
    $A$&= {0:> .3g}&$\pm${1:.3g}\\
    $\mu$&= {2:> .3g}&$\pm${3:.3g}\\
    $\sigma$&= {4:> .3g}&$\pm${5:.3g}\\
\hline
    $p_0$&= {6:> .3g}&$\pm${7:.3g}\\
    $p_1$&= {8:> .3g}&$\pm${9:.3g}\\
    $p_2$&= {10:> .3g}&$\pm${11:.3g}\\
    $p_3$&= {12:> .3g}&$\pm${13:.3g}\\
\hline
\end{{tabular}}

\vskip 5mm

\begin{{tabular}}{{ll}}
  Initial $\chi^2$/d.o.f.:& {14:.3g} \\
  Final $\chi^2$/d.o.f.:& {15:.3g} \\
\end{{tabular}}
'''

#  Signal events:& {16:.3g} \\
#  Background events:& {17:.3g} \\
#  Total events:& {18:.3g} \\
#  {{\bf SBR}}:& {{\bf {19:.3g}}}

bg_table = r'''
\begin{{tabular}}{{lll}}
    $p_0$&= {0:> .3g}&$\pm${1:.3g}\\
    $p_1$&= {2:> .3g}&$\pm${3:.3g}\\
    $p_2$&= {4:> .3g}&$\pm${5:.3g}\\
    $p_3$&= {6:> .3g}&$\pm${7:.3g}\\
    $p_4$&= {8:> .3g}&$\pm${9:.3g}\\
    $p_5$&= {10:> .3g}&$\pm${11:.3g}\\
    $p_6$&= {12:> .3g}&$\pm${13:.3g}\\
\hline
\end{{tabular}}

\vskip 5mm

\begin{{tabular}}{{ll}}
  Initial $\chi^2$/d.o.f.:& {14:.3g} \\
  Final $\chi^2$/d.o.f.:& {15:.3g} \\
\end{{tabular}}
'''


sig_table = r'''
\begin{{tabular}}{{lll}}
    $A$&= {0:> .3g}&$\pm${1:.3g}\\
    $\mu$&= {2:> .3g}&$\pm${3:.3g}\\
    $\sigma$&= {4:> .3g}&$\pm${5:.3g}\\
\hline
\end{{tabular}}

\vskip 5mm

\begin{{tabular}}{{ll}}
  Initial $\chi^2$/d.o.f.:& {6:.3g} \\
  Final $\chi^2$/d.o.f.:& {7:.3g} \\
\end{{tabular}}
'''


table_two_gauss = r'''
\begin{{tabular}}{{lll}}
    $A_1$&= {0:> .3g}&$\pm${1:.3g}\\
    $\mu_1$&= {2:> .3g}&$\pm${3:.3g}\\
    $\sigma_1$&= {4:> .3g}&$\pm${5:.3g}\\
\hline
    $A_2$&= {6:> .3g}&$\pm${7:.3g}\\
    $\mu_2$&= {8:> .3g}&$\pm${9:.3g}\\
    $\sigma_2$&= {10:> .3g}&$\pm${11:.3g}\\
\hline
    $p_0$&= {12:> .3g}&$\pm${13:.3g}\\
    $p_1$&= {14:> .3g}&$\pm${15:.3g}\\
    $p_2$&= {16:> .3g}&$\pm${17:.3g}\\
    $p_3$&= {18:> .3g}&$\pm${19:.3g}\\
\hline
\end{{tabular}}

\vskip 2.5mm

\begin{{tabular}}{{ll}}
  Inital $\chi^2$:& {20:.3g} \\
  Final $\chi^2$:& {21:.3g} \\
  Signal events:& {22:.3g} \\
  Background events:& {23:.3g} \\
  Total events:& {24:.3g} \\
  {{\bf SBR}}:& {{\bf {25:.3g}}}
\end{{tabular}}
'''


table_bw = r'''
\begin{{tabular}}{{lll}}
    $A$&= {0:> .3g}&$\pm${1:.3g}\\
    $M$&= {2:> .4g}&$\pm${3:.3g}\\
    $\Gamma$&= {4:> .4g}&$\pm${5:.3g}
\end{{tabular}}

\vskip 2.5mm

\begin{{tabular}}{{ll}}
  Inital $\chi^2$:& {6:.3g} \\
  Final $\chi^2$:& {7:.3g} \\
  Total events:& {8:.3g} 
\end{{tabular}}
'''


cut_table = r'''
\begin{{tabular}}{{ll}}
  Selected:& {0:.3g} \\
  Total:& {1:.3g}
\end{{tabular}}
'''


def write_cut_table(selected, total):
    tf = tempfile.NamedTemporaryFile(suffix='.tex')
    tf.write(cut_table.format(selected, total))
    tf.seek(0)
    return tf


def write_table(info):
    tf = tempfile.NamedTemporaryFile(suffix='.tex')
    
    tf.write(table.format(*info))
                          
    tf.seek(0)
    return tf

def write_bg_table(info):
    tf = tempfile.NamedTemporaryFile(suffix='.tex')
    
    tf.write(bg_table.format(*info))

    tf.flush()
                          
    tf.seek(0)
    return tf

def write_sig_table(info):
    tf = tempfile.NamedTemporaryFile(suffix='.tex')
    
    tf.write(sig_table.format(*info))

    tf.flush()
                          
    tf.seek(0)
    return tf


def write_table_bw(info):
    tf = tempfile.NamedTemporaryFile(suffix='.tex')
    tf.write(table_bw.format(*info))

    tf.seek(0)
    return tf

def write_table_two_gauss(nf):
    tf = tempfile.NamedTemporaryFile(suffix='.tex')
    
    nsig = nf.nevents_signal()[0]
    nbg = nf.nevents_bg()[0]

    
    tf.write(table_two_gauss.format(nf.sgf.stats.fitpars[0], nf.sgf.stats.errpars[0],
                                    nf.sgf.stats.fitpars[1], nf.sgf.stats.errpars[1],
                                    nf.sgf.stats.fitpars[2], nf.sgf.stats.errpars[2],
                                    nf.sgf.stats.fitpars[3], nf.sgf.stats.errpars[3],
                                    nf.sgf.stats.fitpars[4], nf.sgf.stats.errpars[4],
                                    nf.sgf.stats.fitpars[5], nf.sgf.stats.errpars[5],
                                    nf.bgf.stats.fitpars[0], nf.bgf.stats.errpars[0],
                                    nf.bgf.stats.fitpars[1], nf.bgf.stats.errpars[1],
                                    nf.bgf.stats.fitpars[2], nf.bgf.stats.errpars[2],
                                    nf.bgf.stats.fitpars[3], nf.bgf.stats.errpars[3],
                                    nf.sgf.stats.init_chi2_dof, nf.sgf.stats.final_chi2_dof,
                                    abs(int(nsig)), abs(int(nbg)), int(len(nf.hist)),
                                    nsig/nbg,
                                    ))

    tf.seek(0)
    return tf
    
                          
